home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-04 | 32.3 KB | 1,157 lines | [TEXT/ttxt] |
- TO ABS :NUM
- OP IFELSE (:NUM < 0) [-:NUM] [:NUM]
- END
-
- TO AGEIFY :SENT
- IF EMPTYP :SENT [OUTPUT []]
- IF NOT PERSONP FIRST :SENT [OUTPUT FPUT FIRST :SENT AGEIFY BF :SENT]
- CATCH "ERROR [IF EQUALP FIRST BF :SENT "S ~
- [OUTPUT FPUT FIRST :SENT AGEIFY BF :SENT]]
- OUTPUT (SE FIRST :SENT [S AGE] AGEIFY BF :SENT)
- END
-
- TO AGEPROB
- LOCAL [BEG END SYM WHO NUM SUBJ AGES]
- WHILE [MATCH [^BEG AS OLD AS #END] :PROB] [MAKE "PROB SE :BEG :END]
- WHILE [MATCH [^BEG YEARS OLD #END] :PROB] [MAKE "PROB SE :BEG :END]
- WHILE [MATCH [^BEG WILL BE WHEN #END] :PROB] ~
- [MAKE "SYM GENSYM ~
- MAKE "PROB (SE :BEG "IN :SYM [YEARS . IN] :SYM "YEARS :END)]
- WHILE [MATCH [^BEG WAS WHEN #END] :PROB] ~
- [MAKE "SYM GENSYM ~
- MAKE "PROB (SE :BEG :SYM [YEARS AGO .] :SYM [YEARS AGO] :END)]
- WHILE [MATCH [^BEG !WHO:PERSONP WILL BE IN !NUM YEARS #END] :PROB] ~
- [MAKE "PROB (SE :BEG :WHO [S AGE IN] :NUM "YEARS #END)]
- WHILE [MATCH [^BEG WAS #END] :PROB] [MAKE "PROB (SE :BEG "IS :END)]
- WHILE [MATCH [^BEG WILL BE #END] :PROB] [MAKE "PROB (SE :BEG "IS :END)]
- WHILE [MATCH [^BEG !WHO:PERSONP IS NOW #END] :PROB] ~
- [MAKE "PROB (SE :BEG :WHO [S AGE NOW] :END)]
- WHILE [MATCH [^BEG !NUM YEARS FROM NOW #END] :PROB] ~
- [MAKE "PROB (SE :BEG "IN :NUM "YEARS :END)]
- MAKE "PROB AGEIFY :PROB
- IFELSE MATCH [^ !WHO:PERSONP ^END S AGE #] :PROB ~
- [MAKE "SUBJ SE :WHO :END] [MAKE "SUBJ "SOMEONE]
- MAKE "PROB AGEPRON :PROB
- MAKE "END :PROB
- MAKE "AGES []
- WHILE [MATCH [^ !WHO:PERSONP ^BEG AGE #END] :END] ~
- [PUSH "AGES (SE "AND :WHO :BEG "AGE)]
- MAKE "AGES BF REDUCE "SE REMDUP :AGES
- WHILE [MATCH [^BEG THEIR AGES #END] :PROB] [MAKE "PROB (SE :BEG :AGES :END)]
- MAKE "SIMSEN MAP [AGESEN ?] BRACKET :PROB
- END
-
- TO AGEPRON :SENT
- IF EMPTYP :SENT [OUTPUT []]
- IF NOT PRONOUN FIRST :SENT [OUTPUT FPUT FIRST :SENT AGEPRON BF :SENT]
- IF POSSPRO FIRST :SENT [OUTPUT (SE :SUBJ "S AGEPRON BF :SENT)]
- OUTPUT (SE :SUBJ [S AGE] AGEPRON BF :SENT)
- END
-
- TO AGESEN :SENT
- LOCAL [WHEN REST NUM]
- MAKE "WHEN []
- IF MATCH [IN !NUM YEARS #REST] :SENT ~
- [MAKE "WHEN SE "PLUSS :NUM MAKE "SENT :REST]
- IF MATCH [!NUM YEARS AGO #REST] :SENT ~
- [MAKE "WHEN SE "MINUSS :NUM MAKE "SENT :REST]
- OUTPUT AGEWHEN :SENT
- END
-
- TO AGEWHEN :SENT
- IF EMPTYP :SENT [OUTPUT []]
- IF NOT EQUALP FIRST :SENT "AGE [OUTPUT FPUT FIRST :SENT AGEWHEN BF :SENT]
- IF MATCH [IN !NUM YEARS #REST] BF :SENT ~
- [OUTPUT (SE [AGE PLUSS] :NUM AGEWHEN :REST)]
- IF MATCH [!NUM YEARS AGO #REST] BF :SENT ~
- [OUTPUT (SE [AGE MINUSS] :NUM AGEWHEN :REST)]
- IF EQUALP "NOW FIRST BF :SENT [OUTPUT SE "AGE AGEWHEN BF BF :SENT]
- OUTPUT (SE "AGE :WHEN AGEWHEN BF :SENT)
- END
-
- TO ARTICLE :WORD
- OP MEMBERP :WORD [A AN THE]
- END
-
- TO BKT1 :PROBLIST
- LOCAL [FIRST WORD REST]
- IF EMPTYP :PROBLIST [OUTPUT []]
- IF NOT MEMBERP ", FIRST :PROBLIST [OP FPUT FIRST :PROBLIST BKT1 BF :PROBLIST]
- IF MATCH [IF ^FIRST , !WORD:QWORD #REST] FIRST :PROBLIST ~
- [OP BKT1 FPUT (SE :FIRST ".) FPUT (SE :WORD :REST) BF :PROBLIST]
- IF MATCH [^FIRST , AND #REST] FIRST :PROBLIST ~
- [OP FPUT (SE :FIRST ".) (BKT1 FPUT :REST BF :PROBLIST)]
- OP FPUT FIRST :PROBLIST BKT1 BF :PROBLIST
- END
-
- TO BRACKET :PROB
- OUTPUT BKT1 FINDDELIM :PROB
- END
-
- TO CHANGEONE :CHANGE
- LOCAL "END
- IF NOT MATCH (SE FIRST :CHANGE [#END]) :SENT [OP "FALSE]
- MAKE "SENT RUN (SE "SE LAST :CHANGE ":END)
- OP "TRUE
- END
-
- TO CHANGES :SENT :LIST
- LOCAL "KEYWORDS
- MAKE "KEYWORDS MAP.SE [FINDKEY FIRST ?] :LIST
- OP CHANGES1 :SENT :LIST :KEYWORDS
- END
-
- TO CHANGES1 :SENT :LIST :KEYWORDS
- IF EMPTYP :SENT [OP []]
- IF MEMBERP FIRST :SENT :KEYWORDS [OP CHANGES2 :SENT :LIST :KEYWORDS]
- OP FPUT FIRST :SENT CHANGES1 BF :SENT :LIST :KEYWORDS
- END
-
- TO CHANGES2 :SENT :LIST :KEYWORDS
- CHANGES3 :LIST :LIST
- OP FPUT FIRST :SENT CHANGES1 BF :SENT :LIST :KEYWORDS
- END
-
- TO CHANGES3 :BIGLIST :NOWLIST
- IF EMPTYP :NOWLIST [STOP]
- IF CHANGEONE FIRST :NOWLIST [CHANGES3 :BIGLIST :BIGLIST STOP]
- CHANGES3 :BIGLIST BF :NOWLIST
- END
-
- TO DENOM :FRACT :ADDENDS
- MAKE "ADDENDS SIMPLUS :ADDENDS
- LOCAL "DEN
- MAKE "DEN LAST :FRACT
- IF NOT EQUALP FIRST :ADDENDS "QUOTIENT ~
- [OP SIMDIV LIST ~
- (SIMONE "SUM ~
- (REMOP "SUM LIST (DISTRIBTIMES (LIST :ADDENDS) :DEN) ~
- FIRST BF :FRACT)) :DEN]
- IF EQUALP :DEN LAST :ADDENDS ~
- [OP SIMDIV (SIMPLUS LIST (FIRST BF :FRACT) (FIRST BF :ADDENDS)) :DEN]
- LOCAL "LOWTERMS
- MAKE "LOWTERMS SIMDIV LIST :DEN LAST :ADDENDS
- OP SIMDIV LIST (SIMPLUS (SIMTIMES LIST FIRST BF :FRACT LAST :LOWTERMS) ~
- (SIMTIMES LIST FIRST BF :ADDENDS FIRST BF :LOWTERMS)) ~
- (SIMTIMES LIST FIRST BF :LOWTERMS LAST :ADDENDS)
- END
-
- TO DEPUNCT :WORD
- IF EMPTYP :WORD [OP []]
- IF EQUALP FIRST :WORD "$ [OP SE "$ DEPUNCT BF :WORD]
- IF EQUALP LAST :WORD "% [OP SE DEPUNCT BL :WORD "PERCENT]
- IF MEMBERP LAST :WORD [. ? |;| ,] [OP SE DEPUNCT BL :WORD LAST :WORD]
- IF EMPTYP BF :WORD [OP :WORD]
- IF EQUALP LAST2 :WORD "'S [OP SE DEPUNCT BL BL :WORD "S]
- OP :WORD
- END
-
- TO DISTRIBTIMES :TRMS :MULTIPLIER
- OP SIMPLUS MAP [SIMTIMES (LIST ? :MULTIPLIER)] :TRMS
- END
-
- TO DISTRIBX :EXPR
- LOCAL [OPER ARGS]
- IF EMPTYP :EXPR [OP :EXPR]
- MAKE "OPER FIRST :EXPR
- IF NOT OPERATORP :OPER [OP :EXPR]
- MAKE "ARGS MAP [DISTRIBX ?] BF :EXPR
- IF REDUCE "AND MAP [NUMBERP ?] :ARGS [OP RUN (SE [(] :OPER :ARGS [)])]
- IF EQUALP :OPER "SUM [OP SIMPLUS :ARGS]
- IF EQUALP :OPER "MINUS [OP MINUSIN FIRST :ARGS]
- IF EQUALP :OPER "PRODUCT [OP SIMTIMES :ARGS]
- IF EQUALP :OPER "QUOTIENT [OP SIMDIV :ARGS]
- OP FPUT :OPER :ARGS
- END
-
- TO DIVTERM :DIVIDEND :DIVISOR
- IF EQUALP :DIVIDEND 0 [OP 0]
- OP SIMDIV LIST :DIVIDEND :DIVISOR
- END
-
- TO DLM :WORD
- OP MEMBERP :WORD [. ? |;|]
- END
-
- TO EXPT :NUM :POW
- IF :POW < 1 [OP 1]
- OP :NUM * EXPT :NUM :POW - 1
- END
-
- TO FACTOR :EXPRS :VAR
- LOCAL "TRMS
- MAKE "TRMS MAP [FACTOR1 :VAR ?] :EXPRS
- IF MEMBERP "UNKNOWN :TRMS [OP FPUT "UNKNOWN :EXPRS]
- OP LIST :VAR SIMPLUS :TRMS
- END
-
- TO FACTOR1 :VAR :EXPR
- LOCAL "NEGVAR
- MAKE "NEGVAR MINUSIN :VAR
- IF EQUALP :VAR :EXPR [OP 1]
- IF EQUALP :NEGVAR :EXPR [OP -1]
- IF EMPTYP :EXPR [OP "UNKNOWN]
- IF EQUALP FIRST :EXPR "PRODUCT [OP FACTOR2 BF :EXPR]
- IF NOT EQUALP FIRST :EXPR "QUOTIENT [OP "UNKNOWN]
- LOCAL "DIVIDEND
- MAKE "DIVIDEND FIRST BF :EXPR
- IF EQUALP :VAR :DIVIDEND [OP (LIST "QUOTIENT 1 LAST :EXPR)]
- IF NOT EQUALP FIRST :DIVIDEND "PRODUCT [OP "UNKNOWN]
- LOCAL "RESULT
- MAKE "RESULT FACTOR2 BF :DIVIDEND
- IF EQUALP :RESULT "UNKNOWN [OP "UNKNOWN]
- OP (LIST "QUOTIENT :RESULT LAST :EXPR)
- END
-
- TO FACTOR2 :TRMS
- IF MEMBERP :VAR :TRMS [OP SIMONE "PRODUCT (REMOVE :VAR :TRMS)]
- IF MEMBERP :NEGVAR :TRMS [OP MINUSIN SIMONE "PRODUCT (REMOVE :NEGVAR :TRMS)]
- OP "UNKNOWN
- END
-
- TO FINDDELIM :SENT
- OP FINDDELIM1 :SENT [] []
- END
-
- TO FINDDELIM1 :IN :OUT :SIMPLES
- IF EMPTYP :IN ~
- [IFELSE EMPTYP :OUT [OP :SIMPLES] [OP LPUT (SE :OUT ".) :SIMPLES]]
- IF DLM FIRST :IN ~
- [OP FINDDELIM1 (BF :IN) [] (LPUT (SE :OUT FIRST :IN) :SIMPLES)]
- OP FINDDELIM1 (BF :IN) (SE :OUT FIRST :IN) :SIMPLES
- END
-
- TO FINDKEY :PATTERN
- IF EQUALP FIRST :PATTERN "!:IN [OP FIRST BF :PATTERN]
- IF EQUALP FIRST :PATTERN "?:IN [OP SE (ITEM 2 :PATTERN) (ITEM 3 :PATTERN)]
- OP FIRST :PATTERN
- END
-
- TO GETEQNS :VARS
- OP MAP.SE [GPROP VARKEY ? "EQNS] :VARS
- END
-
- TO IDIOMS :SENT
- LOCAL "NUMBER
- OP CHANGES :SENT ~
- [[[THE SUM OF] ["SUM]] [[SQUARE OF] ["SQUARE]] [[OF] ["NUMOF]] ~
- [[HOW OLD] ["WHAT]] [[IS EQUAL TO] ["IS]] ~
- [[YEARS YOUNGER THAN] [[LESS THAN]]] [[YEARS OLDER THAN] ["PLUS]] ~
- [[PERCENT LESS THAN] ["PERLESS]] [[LESS THAN] ["LESSTHAN]] ~
- [[THESE] ["THE]] [[MORE THAN] ["PLUS]] ~
- [[FIRST TWO NUMBERS] [[THE FIRST NUMBER AND THE SECOND NUMBER]]] ~
- [[THREE NUMBERS] ~
- [[THE FIRST NUMBER AND THE SECOND NUMBER AND THE THIRD NUMBER]]] ~
- [[ONE HALF] [0.5]] [[TWICE] [[2 TIMES]]] ~
- [[$ !NUMBER] [SE :NUMBER "DOLLARS]] [[CONSECUTIVE TO] [[1 PLUS]]] ~
- [[LARGER THAN] ["PLUS]] [[PER CENT] ["PERCENT]] [[HOW MANY] ["HOWM]] ~
- [[IS MULTIPLIED BY] ["ISMULBY]] [[IS DIVIDED BY] ["ISDIVBY]] ~
- [[MULTIPLIED BY] ["TIMES]] [[DIVIDED BY] ["DIVBY]]]
- END
-
- TO LAST2 :WORD
- OP WORD (LAST BL :WORD) (LAST :WORD)
- END
-
- TO LSAY :HERALD :TEXT
- PR []
- PR :HERALD
- PR []
- FOREACH :TEXT [PR ? PR []]
- END
-
- TO MAYBEADD :NUM :REST
- IF EQUALP :NUM 0 [OP :REST]
- OP FPUT :NUM :REST
- END
-
- TO MAYBEMUL :NUM :REST
- IF EQUALP :NUM 1 [OP :REST]
- OP FPUT :NUM :REST
- END
-
- TO MINUSIN :EXPR
- IF EMPTYP :EXPR [OP -1]
- IF EQUALP FIRST :EXPR "SUM [OP FPUT "SUM MAP [MINUSIN ?] BF :EXPR]
- IF EQUALP FIRST :EXPR "MINUS [OP LAST :EXPR]
- IF MEMBERP FIRST :EXPR [PRODUCT QUOTIENT] ~
- [OP FPUT FIRST :EXPR (FPUT (MINUSIN FIRST BF :EXPR) BF BF :EXPR)]
- IF NUMBERP :EXPR [OP MINUS :EXPR]
- OP LIST "MINUS :EXPR
- END
-
- TO NMTEST :EXPR
- IF MATCH [& !:NUMBERP #] :EXPR [SAY [ARGUMENT ERROR:] :EXPR TOPLEVEL]
- IF AND (EQUALP FIRST :EXPR 1) (1 < COUNT :EXPR) ~
- [MAKE "EXPR (SE 1 PLURAL (FIRST BF :EXPR) (BF BF :EXPR))]
- IF AND (NUMBERP FIRST :EXPR) (1 < COUNT :EXPR) ~
- [PUSH "UNITS (LIST FIRST BF :EXPR) ~
- OP (LIST "PRODUCT (FIRST :EXPR) (OPFORM BF :EXPR))]
- IF NUMBERP FIRST :EXPR [OP FIRST :EXPR]
- IF MEMBERP "THIS :EXPR [OP THIS :EXPR]
- IF NOT MEMBERP :EXPR :VAR [PUSH "VAR :EXPR]
- OP :EXPR
- END
-
- TO OCCVAR :VAR :EXPR
- IF EMPTYP :EXPR [OP "FALSE]
- IF WORDP :EXPR [OP EQUALP :VAR :EXPR]
- IF OPERATORP FIRST :EXPR [OP NOT EMPTYP FIND [OCCVAR :VAR ?] BF :EXPR]
- OP EQUALP :VAR :EXPR
- END
-
- TO OP0 :WORD
- OP MEMBERP :WORD [PLUSS MINUSS SQUARED TOTHEPOWER PER SUM DIFFERENCE NUMOF]
- END
-
- TO OP1 :WORD
- OP MEMBERP :WORD [TIMES DIVBY SQUARE]
- END
-
- TO OP2 :WORD
- OP MEMBERP :WORD [PLUS MINUS LESSTHAN PERCENT PERLESS]
- END
-
- TO OPDIFF :LEFT :RIGHT
- OP (LIST "SUM :LEFT (LIST "MINUS :RIGHT))
- END
-
- TO OPERATORP :WORD
- OP MEMBERP :WORD [SUM MINUS PRODUCT QUOTIENT EXPT SQUARE EQUAL]
- END
-
- TO OPFORM :EXPR
- LOCAL [LEFT RIGHT OP]
- IF MATCH [^LEFT !OP:OP2 #RIGHT] :EXPR [OP OPTEST :OP :LEFT :RIGHT]
- IF MATCH [^LEFT !OP:OP1 #RIGHT] :EXPR [OP OPTEST :OP :LEFT :RIGHT]
- IF MATCH [^LEFT !OP:OP0 #RIGHT] :EXPR [OP OPTEST :OP :LEFT :RIGHT]
- IF MATCH [#LEFT !:DLM] :EXPR [MAKE "EXPR :LEFT]
- OP NMTEST FILTER [NOT ARTICLE ?] :EXPR
- END
-
- TO OPREM :SENT
- OP MAP [IFELSE EQUALP ? "NUMOF ["OF] [?]] :SENT
- END
-
- TO OPTEST :OP :LEFT :RIGHT
- OP RUN (LIST (WORD "TST. :OP) :LEFT :RIGHT)
- END
-
- TO PERSONP :WORD
- OUTPUT MEMBERP :WORD [MARY ANN BILL FATHER UNCLE]
- END
-
- TO PLURAL :WORD
- LOCAL "PLURAL
- MAKE "PLURAL GPROP :WORD "PLURAL
- IF NOT EMPTYP :PLURAL [OP :PLURAL]
- IF NOT EMPTYP GPROP :WORD "SING [OP :WORD]
- IF EQUALP LAST :WORD "S [OP :WORD]
- OP WORD :WORD "S
- END
-
- TO POSSPRO :WORD
- OP MEMBERP :WORD [HIS HER ITS]
- END
-
- TO PRANS :ANS :SOLUTION
- LOCAL "RESULT
- MAKE "RESULT FIND [EQUALP FIRST ? FIRST :ANS] :SOLUTION
- IF EMPTYP :RESULT [OP "TRUE]
- PR (SE LAST :ANS "IS UNITSTRING LAST :RESULT)
- PR []
- OP "FALSE
- END
-
- TO PRANSWERS :ANS :SOLUTION
- PR []
- IF EQUALP :SOLUTION "UNSOLVABLE ~
- [PR [UNABLE TO SOLVE THIS SET OF EQUATIONS.] OP "FALSE]
- IF EQUALP :SOLUTION "INSUFFICIENT ~
- [PR [THE EQUATIONS WERE INSUFFICIENT TO FIND A SOLUTION.] OP "FALSE]
- LOCAL "GOTALL
- MAKE "GOTALL "TRUE
- FOREACH :ANS [IF PRANS ? :SOLUTION [MAKE "GOTALL "FALSE]]
- IF NOT :GOTALL [PR [] PR [UNABLE TO SOLVE THIS SET OF EQUATIONS.]]
- OP :GOTALL
- END
-
- TO PRONOUN :WORD
- OP MEMBERP :WORD [HE SHE IT HIM HER THEY THEM HIS HER ITS]
- END
-
- TO QSET :SENT
- LOCAL "OPFORM
- MAKE "OPFORM OPFORM FILTER [NOT ARTICLE ?] :SENT
- IF NOT OPERATORP FIRST :OPFORM ~
- [QUEUE "WANTED :OPFORM QUEUE "ANS LIST :OPFORM OPREM :SENT OP []]
- LOCAL "GENSYM
- MAKE "GENSYM GENSYM
- QUEUE "WANTED :GENSYM
- QUEUE "ANS LIST :GENSYM OPREM :SENT
- OP (LIST "EQUAL :GENSYM OPFORM (FILTER [NOT ARTICLE ?] :SENT))
- END
-
- TO QWORD :WORD
- OP MEMBERP :WORD [FIND WHAT HOWM HOW]
- END
-
- TO REMFACTOR :NUM :DEN
- FOREACH BF :NUM [REMFACTOR1 ?]
- OP (LIST "QUOTIENT (SIMONE "PRODUCT BF :NUM) (SIMONE "PRODUCT BF :DEN))
- END
-
- TO REMFACTOR1 :EXPR
- LOCAL "NEG
- IF MEMBERP :EXPR :DEN ~
- [MAKE "NUM REMOVE :EXPR :NUM MAKE "DEN REMOVE :EXPR :DEN STOP]
- MAKE "NEG MINUSIN :EXPR
- IF NOT MEMBERP :NEG :DEN [STOP]
- MAKE "NUM REMOVE :EXPR :NUM
- MAKE "DEN MINUSIN REMOVE :NEG :DEN
- END
-
- TO REMOP :OPER :EXPRS
- OP MAP.SE [IFELSE EQUALP FIRST ? :OPER [BF ?] [(LIST ?)]] :EXPRS
- END
-
- TO ROUNDOFF :NUM
- IF (ABS (:NUM - ROUND :NUM)) < 0.0001 [OP ROUND :NUM]
- OP :NUM
- END
-
- TO SAY :HERALD :TEXT
- PR []
- PR :HERALD
- PR []
- PR :TEXT
- PR []
- END
-
- TO SENFORM :SENT
- MAKE "LASTEQN SENFORM1 :SENT
- OP :LASTEQN
- END
-
- TO SENFORM1 :SENT
- LOCAL [ONE TWO VERB1 VERB2 STUFF1 STUFF2 FACTOR]
- IF EMPTYP :SENT [OP []]
- IF MATCH [^ WHAT ARE ^ONE AND ^TWO !:DLM] :SENT ~
- [OP FPUT (QSET :ONE) (SENFORM (SE [WHAT ARE] :TWO "?))]
- IF MATCH [^ WHAT !:IN [IS ARE] #ONE !:DLM] :SENT ~
- [OP (LIST QSET :ONE)]
- IF MATCH [^ HOWM !ONE IS #TWO !:DLM] :SENT ~
- [PUSH "AUNITS (LIST :ONE) OP (LIST QSET :TWO)]
- IF MATCH [^ HOWM ^ONE DO ^TWO HAVE !:DLM] :SENT ~
- [OP (LIST QSET (SE [THE NUMBER OF] :ONE :TWO "HAVE))]
- IF MATCH [^ HOWM ^ONE DOES ^TWO HAVE !:DLM] :SENT ~
- [OP (LIST QSET (SE [THE NUMBER OF] :ONE :TWO "HAS))]
- IF MATCH [^ FIND ^ONE AND #TWO] :SENT ~
- [OP FPUT (QSET :ONE) (SENFORM SE "FIND :TWO)]
- IF MATCH [^ FIND #ONE !:DLM] :SENT [OP (LIST QSET :ONE)]
- MAKE "SENT FILTER [NOT ARTICLE ?] :SENT
- IF MATCH [^ONE ISMULBY #TWO] :SENT ~
- [PUSH "REF (LIST "PRODUCT OPFORM :ONE OPFORM :TWO) OP []]
- IF MATCH [^ONE ISDIVBY #TWO] :SENT ~
- [PUSH "REF (LIST "QUOTIENT OPFORM :ONE OPFORM :TWO) OP []]
- IF MATCH [^ONE IS INCREASED BY #TWO] :SENT ~
- [PUSH "REF (LIST "SUM OPFORM :ONE OPFORM :TWO) OP []]
- IF MATCH [^ONE IS #TWO] :SENT ~
- [OP (LIST (LIST "EQUAL OPFORM :ONE OPFORM :TWO))]
- IF MATCH ~
- [^ONE !VERB1:VERB ^FACTOR AS MANY ^STUFF1 AS ^TWO !VERB2:VERB ^STUFF2 !:DLM] ~
- :SENT ~
- [IF EMPTYP :STUFF2 [MAKE "STUFF2 :STUFF1] ~
- OP (LIST (LIST "EQUAL ~
- OPFORM (SE [THE NUMBER OF] :STUFF1 :ONE :VERB1) ~
- OPFORM (SE :FACTOR [THE NUMBER OF] :STUFF2 :TWO :VERB2)))]
- IF MATCH [^ONE !VERB1:VERB !FACTOR:NUMBERP #STUFF1 !:DLM] :SENT ~
- [OP (LIST (LIST "EQUAL ~
- OPFORM (SE [THE NUMBER OF] :STUFF1 :ONE :VERB1) ~
- OPFORM (LIST :FACTOR)))]
- SAY [THIS SENTENCE FORM IS NOT RECOGNIZED:] :SENT
- TOPLEVEL
- END
-
- TO SETMINUS :BIG :LITTLE
- OP FILTER [NOT MEMBERP ? :LITTLE] :BIG
- END
-
- TO SIMDIV :LIST
- LOCAL [NUM DEN NUMOP DENOP]
- MAKE "NUM FIRST :LIST
- MAKE "DEN LAST :LIST
- IF EQUALP :NUM :DEN [OP 1]
- IF NUMBERP :DEN [OP SIMTIMES (LIST (QUOTIENT 1 :DEN) :NUM)]
- MAKE "NUMOP FIRST :NUM
- MAKE "DENOP FIRST :DEN
- IF EQUALP :NUMOP "QUOTIENT ~
- [OP SIMDIV LIST (FIRST BF :NUM) (SIMTIMES LIST LAST :NUM :DEN)]
- IF EQUALP :DENOP "QUOTIENT ~
- [OP SIMDIV LIST (SIMTIMES LIST :NUM LAST :DEN) (FIRST BF :DEN)]
- IF AND EQUALP :NUMOP "PRODUCT EQUALP :DENOP "PRODUCT [OP REMFACTOR :NUM :DEN]
- IF AND EQUALP :NUMOP "PRODUCT MEMBERP :DEN :NUM [OP REMOVE :DEN :NUM]
- OP FPUT "QUOTIENT :LIST
- END
-
- TO SIMONE :OPER :TRMS
- IF EMPTYP :TRMS [OP IFELSE EQUALP :OPER "PRODUCT [1] [0]]
- IF EMPTYP BF :TRMS [OP FIRST :TRMS]
- OP FPUT :OPER :TRMS
- END
-
- TO SIMPLUS :EXPRS
- MAKE "EXPRS REMOP "SUM :EXPRS
- LOCAL "FACTOR
- MAKE "FACTOR [UNKNOWN]
- CATCH "SIMPLUS ~
- [FOREACH :TERMS ~
- [MAKE "FACTOR (FACTOR :EXPRS ?) ~
- IF NOT EQUALP FIRST :FACTOR "UNKNOWN [THROW "SIMPLUS]]]
- IF NOT EQUALP FIRST :FACTOR "UNKNOWN [OP FPUT "PRODUCT REMOP "PRODUCT :FACTOR]
- LOCAL [NUMS NONNUMS QUICK]
- MAKE "NUMS 0
- MAKE "NONNUMS []
- MAKE "QUICK []
- CATCH "SIMPLUS [SIMPLUS1 :EXPRS]
- IF NOT EMPTYP :QUICK [OP :QUICK]
- IF NOT EQUALP :NUMS 0 [PUSH "NONNUMS :NUMS]
- OP SIMONE "SUM :NONNUMS
- END
-
- TO SIMPLUS1 :EXPRS
- IF EMPTYP :EXPRS [STOP]
- SIMPLUS2 FIRST :EXPRS
- SIMPLUS1 BF :EXPRS
- END
-
- TO SIMPLUS2 :POS
- LOCAL "NEG
- MAKE "NEG MINUSIN :POS
- IF NUMBERP :POS [MAKE "NUMS SUM :POS :NUMS STOP]
- IF MEMBERP :NEG BF :EXPRS [MAKE "EXPRS REMOVE :NEG :EXPRS STOP]
- IF EQUALP FIRST :POS "QUOTIENT ~
- [MAKE "QUICK (DENOM :POS (MAYBEADD :NUMS SE :NONNUMS BF :EXPRS)) ~
- THROW "SIMPLUS]
- PUSH "NONNUMS :POS
- END
-
- TO SIMTIMES :EXPRS
- LOCAL [NUMS NONNUMS QUICK]
- MAKE "NUMS 1
- MAKE "NONNUMS []
- MAKE "QUICK []
- CATCH "SIMTIMES [FOREACH REMOP "PRODUCT :EXPRS [SIMTIMES1 ?]]
- IF NOT EMPTYP :QUICK [OP :QUICK]
- IF EQUALP :NUMS 0 [OP 0]
- IF NOT EQUALP :NUMS 1 [PUSH "NONNUMS :NUMS]
- OP SIMONE "PRODUCT :NONNUMS
- END
-
- TO SIMTIMES1 :EXPR
- IF EQUALP :EXPR 0 [MAKE "NUMS 0 THROW "SIMTIMES]
- IF NUMBERP :EXPR [MAKE "NUMS PRODUCT :EXPR :NUMS STOP]
- IF EQUALP FIRST :EXPR "SUM ~
- [MAKE "QUICK DISTRIBTIMES (BF :EXPR) ~
- (SIMONE "PRODUCT MAYBEMUL :NUMS SE :NONNUMS ?REST) ~
- THROW "SIMTIMES]
- IF EQUALP FIRST :EXPR "QUOTIENT ~
- [MAKE "QUICK ~
- SIMDIV (LIST (SIMTIMES (LIST (FIRST BF :EXPR) ~
- (SIMONE "PRODUCT ~
- MAYBEMUL :NUMS ~
- SE :NONNUMS ?REST))) ~
- (LAST :EXPR)) ~
- THROW "SIMTIMES]
- PUSH "NONNUMS :EXPR
- END
-
- TO SINGULAR :WORD
- LOCAL "SING
- MAKE "SING GPROP :WORD "SING
- IF NOT EMPTYP :SING [OP :SING]
- IF NOT EMPTYP GPROP :WORD "PLURAL [OP :WORD]
- IF EQUALP LAST :WORD "S [OP BL :WORD]
- OP :WORD
- END
-
- TO SOLVE :WANTED :EQT :TERMS
- OP SOLVE.REDUCE SOLVER :WANTED :TERMS [] [] "INSUFFICIENT
- END
-
- TO SOLVE.REDUCE :SOLN
- IF EMPTYP :SOLN [OP []]
- IF WORDP :SOLN [OP :SOLN]
- IF EMPTYP BF :SOLN [OP :SOLN]
- LOCAL "PART
- MAKE "PART SOLVE.REDUCE BF :SOLN
- OP FPUT (LIST (FIRST FIRST :SOLN) (SUBORD LAST FIRST :SOLN :PART)) :PART
- END
-
- TO SOLVE1 :X :TERMS :ALIS :EQNS :FAILED :ERR
- LOCAL [THISEQ VARS EXTRAS XTERMS OTHERS RESULT]
- IF EMPTYP :EQNS [OP :ERR]
- MAKE "THISEQ SUBORD (FIRST :EQNS) :ALIS
- MAKE "VARS VARTERMS :THISEQ
- IF NOT MEMBERP :X :VARS ~
- [OP SOLVE1 :X :TERMS :ALIS (BF :EQNS) (FPUT FIRST :EQNS :FAILED) :ERR]
- MAKE "XTERMS FPUT :X :TERMS
- MAKE "EXTRAS SETMINUS :VARS :XTERMS
- MAKE "EQT REMOVE (FIRST :EQNS) :EQT
- IF NOT EMPTYP :EXTRAS ~
- [MAKE "OTHERS SOLVER :EXTRAS :XTERMS :ALIS [] "INSUFFICIENT ~
- IFELSE WORDP :OTHERS ~
- [MAKE "EQT SE :FAILED :EQNS ~
- OP SOLVE1 :X :TERMS :ALIS (BF :EQNS) ~
- (FPUT FIRST :EQNS :FAILED) :OTHERS] ~
- [MAKE "ALIS :OTHERS ~
- MAKE "THISEQ SUBORD (FIRST :EQNS) :ALIS]]
- MAKE "RESULT SOLVEQ :X :THISEQ
- IF LISTP :RESULT [OP LPUT :RESULT :ALIS]
- MAKE "EQT SE :FAILED :EQNS
- OP SOLVE1 :X :TERMS :ALIS (BF :EQNS) (FPUT FIRST :EQNS :FAILED) :RESULT
- END
-
- TO SOLVEQ :VAR :EQN
- LOCAL [LEFT RIGHT]
- MAKE "LEFT FIRST BF :EQN
- IFELSE OCCVAR :VAR :LEFT ~
- [MAKE "RIGHT LAST :EQN] [MAKE "RIGHT :LEFT MAKE "LEFT LAST :EQN]
- OP SOLVEQ1 :LEFT :RIGHT "TRUE
- END
-
- TO SOLVEQ.MINUS
- OP SOLVEQ1 (FIRST BF :LEFT) (MINUSIN :RIGHT) "FALSE
- END
-
- TO SOLVEQ.PRODUCT
- OP SOLVEQ.PRODUCT1 :LEFT :RIGHT
- END
-
- TO SOLVEQ.PRODUCT1 :LEFT :RIGHT
- IF EMPTYP BF BF :LEFT [OP SOLVEQ1 (FIRST BF :LEFT) :RIGHT "TRUE]
- IF NOT OCCVAR :VAR FIRST BF :LEFT ~
- [OP SOLVEQ.PRODUCT1 (FPUT "PRODUCT BF BF :LEFT) ~
- (DIVTERM :RIGHT FIRST BF :LEFT)]
- LOCAL "REST
- MAKE "REST SIMONE "PRODUCT BF BF :LEFT
- IF OCCVAR :VAR :REST [OP "UNSOLVABLE]
- OP SOLVEQ1 (FIRST BF :LEFT) (DIVTERM :RIGHT :REST) "FALSE
- END
-
- TO SOLVEQ.QUOTIENT
- IF OCCVAR :VAR FIRST BF :LEFT ~
- [OP SOLVEQ1 (FIRST BF :LEFT) (SIMTIMES LIST :RIGHT LAST :LEFT) "TRUE]
- OP SOLVEQ1 (SIMTIMES LIST :RIGHT LAST :LEFT) (FIRST BF :LEFT) "TRUE
- END
-
- TO SOLVEQ.RPLUS :LEFT :RIGHT :NEWRIGHT
- IF EMPTYP :RIGHT [OP SOLVEQ1 :LEFT (SIMONE "SUM :NEWRIGHT) "FALSE]
- IF OCCVAR :VAR FIRST :RIGHT ~
- [OP SOLVEQ.RPLUS (SUBTERM :LEFT FIRST :RIGHT) BF :RIGHT :NEWRIGHT]
- OP SOLVEQ.RPLUS :LEFT BF :RIGHT (FPUT FIRST :RIGHT :NEWRIGHT)
- END
-
- TO SOLVEQ.SUM
- IF EMPTYP BF BF :LEFT [OP SOLVEQ1 FIRST BF :LEFT :RIGHT "TRUE]
- OP SOLVEQ.SUM1 BF :LEFT :RIGHT []
- END
-
- TO SOLVEQ.SUM1 :LEFT :RIGHT :NEWLEFT
- IF EMPTYP :LEFT [OP SOLVEQ.SUM2]
- IF OCCVAR :VAR FIRST :LEFT ~
- [OP SOLVEQ.SUM1 BF :LEFT :RIGHT FPUT FIRST :LEFT :NEWLEFT]
- OP SOLVEQ.SUM1 BF :LEFT (SUBTERM :RIGHT FIRST :LEFT) :NEWLEFT
- END
-
- TO SOLVEQ.SUM2
- IF EMPTYP BF :NEWLEFT [OP SOLVEQ1 FIRST :NEWLEFT :RIGHT "TRUE]
- LOCAL "FACTOR
- MAKE "FACTOR FACTOR :NEWLEFT :VAR
- IF EQUALP FIRST :FACTOR "UNKNOWN [OP "UNSOLVABLE]
- IF EQUALP LAST :FACTOR 0 [OP "UNSOLVABLE]
- OP SOLVEQ1 FIRST :FACTOR (DIVTERM :RIGHT LAST :FACTOR) "TRUE
- END
-
- TO SOLVEQ1 :LEFT :RIGHT :BOTHTEST
- IF :BOTHTEST [IF OCCVAR :VAR :RIGHT [OP SOLVEQBOTH :LEFT :RIGHT]]
- IF EQUALP :LEFT :VAR [OP LIST :VAR :RIGHT]
- IF WORDP :LEFT [OP "UNSOLVABLE]
- LOCAL "OPER
- MAKE "OPER FIRST :LEFT
- IF MEMBERP :OPER [SUM PRODUCT MINUS QUOTIENT] [OP RUN (LIST WORD "SOLVEQ. :OPER)]
- OP "UNSOLVABLE
- END
-
- TO SOLVEQBOTH :LEFT :RIGHT
- IF NOT EQUALP FIRST :RIGHT "SUM [OP SOLVEQ1 (SUBTERM :LEFT :RIGHT) 0 "FALSE]
- OP SOLVEQ.RPLUS :LEFT BF :RIGHT []
- END
-
- TO SOLVER :WANTED :TERMS :ALIS :FAILED :ERR
- LOCAL [ONE RESULT RESTWANT]
- IF EMPTYP :WANTED [OP :ERR]
- MAKE "ONE SOLVE1 (FIRST :WANTED) ~
- (SE BF :WANTED :FAILED :TERMS) :ALIS :EQT [] "INSUFFICIENT
- IF WORDP :ONE ~
- [OP SOLVER (BF :WANTED) :TERMS :ALIS (FPUT FIRST :WANTED :FAILED) :ONE]
- MAKE "RESTWANT (SE :FAILED BF :WANTED)
- IF EMPTYP :RESTWANT [OP :ONE]
- MAKE "RESULT SOLVER :RESTWANT :TERMS :ONE [] "INSUFFICIENT
- IF LISTP :RESULT [OP :RESULT]
- OP SOLVER (BF :WANTED) :TERMS :ALIS (FPUT FIRST :WANTED :FAILED) :ONE
- END
-
- TO SQUARE :X
- OP :X * :X
- END
-
- TO STUDENT :PROB
- LOCAL "ORGPROB
- SAY [THE PROBLEM TO BE SOLVED IS] :PROB
- MAKE "PROB MAP.SE [DEPUNCT ?] :PROB
- MAKE "ORGPROB :PROB
- STUDENT1 :PROB ~
- [[[THE PERIMETER OF ! RECTANGLE] ~
- [TWICE THE SUM OF THE LENGTH AND WIDTH OF THE RECTANGLE]] ~
- [[TWO NUMBERS] [ONE OF THE NUMBERS AND THE OTHER NUMBER]] ~
- [[TWO NUMBERS] [ONE NUMBER AND THE OTHER NUMBER]]]
- END
-
- TO STUDENT1 :PROB :IDIOMS
- LOCAL [SIMSEN SHELF AUNITS UNITS WANTED ANS VAR LASTEQN ~
- REF EQT1 BEG END IDIOM REPLY]
- MAKE "PROB IDIOMS :PROB
- IF MATCH [^ TWO NUMBERS #] :PROB ~
- [MAKE "IDIOM FIND [MATCH (SE "^BEG FIRST ? "#END) :ORGPROB] :IDIOMS ~
- TRYIDIOM STOP]
- WHILE [MATCH [^BEG THE THE #END] :PROB] [MAKE "PROB (SE :BEG "THE :END)]
- SAY [WITH MANDATORY SUBSTITUTIONS THE PROBLEM IS] :PROB
- IFELSE MATCH [# @:IN [[AS OLD AS] [AGE] [YEARS OLD]] #] :PROB ~
- [AGEPROB] [MAKE "SIMSEN BRACKET :PROB]
- LSAY [THE SIMPLE SENTENCES ARE] :SIMSEN
- MAKE "AUNITS []
- MAKE "WANTED []
- MAKE "ANS []
- MAKE "VAR []
- MAKE "LASTEQN []
- MAKE "REF []
- MAKE "UNITS []
- MAKE "SHELF FILTER [NOT EMPTYP ?] MAP.SE [SENFORM ?] :SIMSEN
- LSAY [THE EQUATIONS TO BE SOLVED ARE] :SHELF
- MAKE "UNITS REMDUP :UNITS
- IF TRYSOLVE :SHELF :WANTED :UNITS :AUNITS [PR [THE PROBLEM IS SOLVED.] STOP]
- MAKE "EQT1 REMDUP GETEQNS :VAR
- IF NOT EMPTYP :EQT1 [LSAY [USING THE FOLLOWING KNOWN RELATIONSHIPS] :EQT1]
- STUDENT2 :EQT1
- END
-
- TO STUDENT2 :EQT1
- MAKE "VAR REMDUP SE (MAP.SE [VARTERMS ?] :EQT1) :VAR
- MAKE "EQT1 SE :EQT1 VARTEST :VAR
- IF NOT EMPTYP :EQT1 ~
- [IF TRYSOLVE (SE :SHELF :EQT1) :WANTED :UNITS :AUNITS ~
- [PR [THE PROBLEM IS SOLVED.] STOP]]
- MAKE "IDIOM FIND [MATCH (SE "^BEG FIRST ? "#END) :ORGPROB] :IDIOMS
- IF NOT EMPTYP :IDIOM [TRYIDIOM STOP]
- LSAY [DO YOU KNOW ANY MORE RELATIONSHIPS AMONG THESE VARIABLES?] :VAR
- MAKE "REPLY RL
- IF EQUALP :REPLY [YES] [PR [TELL ME.] MAKE "REPLY RL]
- IF EQUALP :REPLY [NO] [PR [] PR [I CAN'T SOLVE THIS PROBLEM.] STOP]
- MAKE "REPLY MAP.SE [DEPUNCT ?] :REPLY
- IF DLM LAST :REPLY [MAKE "REPLY BL :REPLY]
- IF NOT MATCH [^BEG IS #END] :REPLY [PR [I DON'T UNDERSTAND THAT.] STOP]
- MAKE "SHELF SE :SHELF :EQT1
- STUDENT2 (LIST (LIST "EQUAL OPFORM :BEG OPFORM :END))
- END
-
- TO SUBORD :EXPR :ALIST
- OP DISTRIBX SUBORD1 :EXPR :ALIST
- END
-
- TO SUBORD1 :EXPR :ALIST
- IF EMPTYP :ALIST [OP :EXPR]
- OP SUBORD (SUBSTOP (LAST FIRST :ALIST) (FIRST FIRST :ALIST) :EXPR) ~
- (BF :ALIST)
- END
-
- TO SUBSTOP :VAL :VAR :EXPR
- IF EMPTYP :EXPR [OP []]
- IF EQUALP :EXPR :VAR [OP :VAL]
- IF NOT OPERATORP FIRST :EXPR [OP :EXPR]
- OP FPUT FIRST :EXPR MAP [SUBSTOP :VAL :VAR ?] BF :EXPR
- END
-
- TO SUBTERM :MINUEND :SUBTRAHEND
- IF EQUALP :MINUEND 0 [OP MINUSIN :SUBTRAHEND]
- IF EQUALP :MINUEND :SUBTRAHEND [OP 0]
- OP SIMPLUS (LIST :MINUEND MINUSIN :SUBTRAHEND)
- END
-
- TO THIS :EXPR
- IF NOT EMPTYP :REF [OP POP "REF]
- IF NOT EMPTYP :LASTEQN [OP FIRST BF LAST :LASTEQN]
- IF EQUALP FIRST :EXPR "THIS [MAKE "EXPR BF :EXPR]
- PUSH "VAR :EXPR
- OP :EXPR
- END
-
- TO TRYIDIOM
- MAKE "PROB (SE :BEG LAST :IDIOM :END)
- WHILE [MATCH (SE "^BEG FIRST :IDIOM "#END) :PROB] ~
- [MAKE "PROB (SE :BEG LAST :IDIOM :END)]
- SAY [THE PROBLEM WITH AN IDIOMATIC SUBSTITUTION IS] :PROB
- STUDENT1 :PROB (REMOVE :IDIOM :IDIOMS)
- END
-
- TO TRYSOLVE :SHELF :WANTED :UNITS :AUNITS
- LOCAL "SOLUTION
- MAKE "SOLUTION SOLVE :WANTED :SHELF (IFELSE EMPTYP :AUNITS [:UNITS] [:AUNITS])
- OP PRANSWERS :ANS :SOLUTION
- END
-
- TO TST.DIFFERENCE :LEFT :RIGHT
- LOCAL [ONE TWO]
- IF MATCH [BETWEEN ^ONE AND #TWO] :RIGHT [OP OPDIFF OPFORM :ONE OPFORM :TWO]
- SAY [INCORRECT USE OF DIFFERENCE:] :RIGHT
- TOPLEVEL
- END
-
- TO TST.DIVBY :LEFT :RIGHT
- OP (LIST "QUOTIENT OPFORM :LEFT OPFORM :RIGHT)
- END
-
- TO TST.LESSTHAN :LEFT :RIGHT
- OP OPDIFF OPFORM :RIGHT OPFORM :LEFT
- END
-
- TO TST.MINUS :LEFT :RIGHT
- IF EMPTYP :LEFT [OP LIST "MINUS OPFORM :RIGHT]
- OP OPDIFF OPFORM :LEFT OPFORM :RIGHT
- END
-
- TO TST.MINUSS :LEFT :RIGHT
- OP TST.MINUS :LEFT :RIGHT
- END
-
- TO TST.NUMOF :LEFT :RIGHT
- IF NUMBERP LAST :LEFT [OP (LIST "PRODUCT OPFORM :LEFT OPFORM :RIGHT)]
- OP OPFORM (SE :LEFT "OF :RIGHT)
- END
-
- TO TST.PER :LEFT :RIGHT
- OP (LIST "QUOTIENT ~
- OPFORM :LEFT ~
- OPFORM (IFELSE NUMBERP FIRST :RIGHT [:RIGHT] [FPUT 1 :RIGHT]))
- END
-
- TO TST.PERCENT :LEFT :RIGHT
- IF NOT NUMBERP LAST :LEFT ~
- [SAY [INCORRECT USE OF PERCENT:] :LEFT TOPLEVEL]
- OP OPFORM (SE BL :LEFT ((LAST :LEFT) / 100) :RIGHT)
- END
-
- TO TST.PERLESS :LEFT :RIGHT
- IF NOT NUMBERP LAST :LEFT ~
- [SAY [INCORRECT USE OF PERCENT:] :LEFT TOPLEVEL]
- OP (LIST "PRODUCT ~
- (OPFORM SE BL :LEFT ((100 - (LAST :LEFT)) / 100)) ~
- OPFORM :RIGHT)
- END
-
- TO TST.PLUS :LEFT :RIGHT
- OP (LIST "SUM OPFORM :LEFT OPFORM :RIGHT)
- END
-
- TO TST.PLUSS :LEFT :RIGHT
- OP TST.PLUS :LEFT :RIGHT
- END
-
- TO TST.SQUARE :LEFT :RIGHT
- OP LIST "SQUARE OPFORM :RIGHT
- END
-
- TO TST.SQUARED :LEFT :RIGHT
- OP LIST "SQUARE OPFORM :LEFT
- END
-
- TO TST.SUM :LEFT :RIGHT
- LOCAL [ONE TWO THREE]
- IF MATCH [^ONE AND ^TWO AND #THREE] :RIGHT ~
- [OP (LIST "SUM OPFORM :ONE OPFORM (SE "SUM :TWO "AND :THREE))]
- IF MATCH [^ONE AND #TWO] :RIGHT ~
- [OP (LIST "SUM OPFORM :ONE OPFORM :TWO)]
- SAY [SUM USED WRONG:] :RIGHT
- TOPLEVEL
- END
-
- TO TST.TIMES :LEFT :RIGHT
- IF EMPTYP :LEFT [SAY [INCORRECT USE OF TIMES:] :RIGHT TOPLEVEL]
- OP (LIST "PRODUCT OPFORM :LEFT OPFORM :RIGHT)
- END
-
- TO TST.TOTHEPOWER :LEFT :RIGHT
- OP (LIST "EXPT OPFORM :LEFT OPFORM :RIGHT)
- END
-
- TO UNITSTRING :EXPR
- IF NUMBERP :EXPR [OP ROUNDOFF :EXPR]
- IF EQUALP FIRST :EXPR "PRODUCT ~
- [OP SE (UNITSTRING FIRST BF :EXPR) (REDUCE "SE BF BF :EXPR)]
- IF (AND (LISTP :EXPR) ~
- (NOT NUMBERP FIRST :EXPR) ~
- (NOT OPERATORP FIRST :EXPR)) ~
- [OP (SE 1 (SINGULAR FIRST :EXPR) (BF :EXPR))]
- OP :EXPR
- END
-
- TO VAREQUAL :TARGET :VAR
- PR []
- PR [ASSUMING THAT]
- PR (SE (LIST :TARGET) [IS EQUAL TO] (LIST :VAR))
- OP (LIST "EQUAL :TARGET :VAR)
- END
-
- TO VARKEY :VAR
- LOCAL "WORD
- IF MATCH [NUMBER OF !WORD #] :VAR [OP :WORD]
- OP FIRST :VAR
- END
-
- TO VARTERMS :EXPR
- IF EMPTYP :EXPR [OP []]
- IF NUMBERP :EXPR [OP []]
- IF WORDP :EXPR [OP (LIST :EXPR)]
- IF OPERATORP FIRST :EXPR [OP MAP.SE [VARTERMS ?] BF :EXPR]
- OP (LIST :EXPR)
- END
-
- TO VARTEST :VARS
- IF EMPTYP :VARS [OP []]
- LOCAL [VAR BEG END]
- MAKE "VAR FIRST :VARS
- OP (SE (IFELSE MATCH [^BEG !:PRONOUN #END] :VAR ~
- [VARTEST1 :VAR (SE :BEG "& :END) BF :VARS] ~
- [[]]) ~
- (VARTEST1 :VAR (SE "# :VAR "#) BF :VARS) (VARTEST BF :VARS))
- END
-
- TO VARTEST1 :TARGET :PAT :VARS
- OP MAP [VAREQUAL :TARGET ?] FILTER [MATCH :PAT ?] :VARS
- END
-
- TO VERB :WORD
- OP MEMBERP :WORD [HAVE HAS GET GETS WEIGH WEIGHS]
- END
-
- TO MATCH :PAT :SEN
- IF PREMATCH :PAT :SEN [OP RMATCH :PAT :SEN]
- OP "FALSE
- END
-
- TO PREMATCH :PAT :SEN
- IF EMPTYP :PAT [OP "TRUE]
- IF LISTP FIRST :PAT [OP PREMATCH BF :PAT :SEN]
- IF MEMBERP FIRST FIRST :PAT [! @ # ^ & ?] [OP PREMATCH BF :PAT :SEN]
- IF EMPTYP :SEN [OP "FALSE]
- IF MEMBERP FIRST :PAT :SEN [OP PREMATCH BF :PAT :SEN]
- OP "FALSE
- END
-
- TO MATCH!
- IF EMPTYP :SEN [OP "FALSE]
- IF NOT TRY.PRED [OP "FALSE]
- MAKE :SPECIAL.VAR FIRST :SEN
- OP RMATCH BF :PAT BF :SEN
- END
-
- TO MATCH#
- MAKE :SPECIAL.VAR []
- OP #TEST #GATHER :SEN
- END
-
- TO #GATHER :SEN
- IF EMPTYP :SEN [OP :SEN]
- IF NOT TRY.PRED [OP :SEN]
- MAKE :SPECIAL.VAR LPUT FIRST :SEN THING :SPECIAL.VAR
- OP #GATHER BF :SEN
- END
-
- TO #TEST :SEN
- IF RMATCH BF :PAT :SEN [OP "TRUE]
- IF EMPTYP THING :SPECIAL.VAR [OP "FALSE]
- OP #TEST2 FPUT LAST THING :SPECIAL.VAR :SEN
- END
-
- TO #TEST2 :SEN
- MAKE :SPECIAL.VAR BL THING :SPECIAL.VAR
- OP #TEST :SEN
- END
-
- TO MATCH&
- OP &TEST MATCH#
- END
-
- TO &TEST :TF
- IF EMPTYP THING :SPECIAL.VAR [OP "FALSE]
- OP :TF
- END
-
- TO MATCH?
- MAKE :SPECIAL.VAR []
- IF EMPTYP :SEN [OP RMATCH BF :PAT :SEN]
- IF NOT TRY.PRED [OP RMATCH BF :PAT :SEN]
- MAKE :SPECIAL.VAR FIRST :SEN
- IF RMATCH BF :PAT BF :SEN [OP "TRUE]
- MAKE :SPECIAL.VAR []
- OP RMATCH BF :PAT :SEN
- END
-
- TO MATCH@
- MAKE :SPECIAL.VAR :SEN
- OP @TEST []
- END
-
- TO @TEST :SEN
- IF @TRY.PRED [IF RMATCH BF :PAT :SEN [OP "TRUE]]
- IF EMPTYP THING :SPECIAL.VAR [OP "FALSE]
- OP @TEST2 FPUT LAST THING :SPECIAL.VAR :SEN
- END
-
- TO @TEST2 :SEN
- MAKE :SPECIAL.VAR BL THING :SPECIAL.VAR
- OP @TEST :SEN
- END
-
- TO @TRY.PRED
- IF LISTP :SPECIAL.PRED [OP RMATCH :SPECIAL.PRED THING :SPECIAL.VAR]
- OP RUN LIST :SPECIAL.PRED THING :SPECIAL.VAR
- END
-
- TO MATCH^
- MAKE :SPECIAL.VAR []
- OUTPUT ^TEST :SEN
- END
-
- TO ^TEST :SEN
- IF RMATCH BF :PAT :SEN [OUTPUT "TRUE]
- IF EMPTYP :SEN [OUTPUT "FALSE]
- IF NOT TRY.PRED [OUTPUT "FALSE]
- MAKE :SPECIAL.VAR LPUT FIRST :SEN THING :SPECIAL.VAR
- OUTPUT ^TEST BF :SEN
- END
-
- TO ALWAYS :X
- OP "TRUE
- END
-
- TO ANYOF :SEN
- OP ANYOF1 :SEN :IN.LIST
- END
-
- TO ANYOF1 :SEN :PATS
- IF EMPTYP :PATS [OP "FALSE]
- IF RMATCH FIRST :PATS :SEN [OP "TRUE]
- OP ANYOF1 :SEN BF :PATS
- END
-
- TO IN :WORD
- OP MEMBERP :WORD :IN.LIST
- END
-
- TO RMATCH :PAT :SEN
- LOCAL [SPECIAL.VAR SPECIAL.PRED SPECIAL.BUFFER IN.LIST]
- IF OR WORDP :PAT WORDP :SEN [OP "FALSE]
- IF EMPTYP :PAT [OP EMPTYP :SEN]
- IF LISTP FIRST :PAT [OP SPECIAL FPUT "!: :PAT :SEN]
- IF MEMBERP FIRST FIRST :PAT [? # ! & @ ^] [OP SPECIAL :PAT :SEN]
- IF EMPTYP :SEN [OP "FALSE]
- IF EQUALP FIRST :PAT FIRST :SEN [OP RMATCH BF :PAT BF :SEN]
- OP "FALSE
- END
-
- TO PARSE.SPECIAL :WORD :VAR
- IF EMPTYP :WORD [OP LIST :VAR "ALWAYS]
- IF EQUALP FIRST :WORD ": [OP LIST :VAR BF :WORD]
- OP PARSE.SPECIAL BF :WORD WORD :VAR FIRST :WORD
- END
-
- TO QUOTED :THING
- IF LISTP :THING [OP :THING]
- OP WORD "" :THING
- END
-
- TO SET.IN
- MAKE "IN.LIST FIRST BF :PAT
- MAKE "PAT FPUT FIRST :PAT BF BF :PAT
- END
-
- TO SET.SPECIAL :LIST
- MAKE "SPECIAL.VAR FIRST :LIST
- MAKE "SPECIAL.PRED LAST :LIST
- IF EMPTYP :SPECIAL.VAR [MAKE "SPECIAL.VAR "SPECIAL.BUFFER]
- IF MEMBERP :SPECIAL.PRED [IN ANYOF] [SET.IN]
- IF NOT EMPTYP :SPECIAL.PRED [STOP]
- MAKE "SPECIAL.PRED FIRST BF :PAT
- MAKE "PAT FPUT FIRST :PAT BF BF :PAT
- END
-
- TO SPECIAL :PAT :SEN
- SET.SPECIAL PARSE.SPECIAL BF FIRST :PAT "
- OP RUN FPUT WORD "MATCH FIRST FIRST :PAT []
- END
-
- TO TRY.PRED
- IF LISTP :SPECIAL.PRED [OP RMATCH :SPECIAL.PRED FIRST :SEN]
- OP RUN LIST :SPECIAL.PRED QUOTED FIRST :SEN
- END
-
- MAKE "ANN [MARY IS TWICE AS OLD AS ANN WAS WHEN MARY WAS AS OLD AS ANN IS NOW. ~
- IF MARY IS 24 YEARS OLD, HOW OLD IS ANN?]
- MAKE "GUNS [THE NUMBER OF SOLDIERS THE RUSSIANS HAVE IS ~
- ONE HALF OF THE NUMBER OF GUNS THEY HAVE. THEY HAVE 7000 GUNS. ~
- HOW MANY SOLDIERS DO THEY HAVE?]
- MAKE "JET [THE DISTANCE FROM NEW YORK TO LOS ANGELES IS 3000 MILES. ~
- IF THE AVERAGE SPEED OF A JET PLANE IS 600 MILES PER HOUR, ~
- FIND THE TIME IT TAKES TO TRAVEL FROM NEW YORK TO LOS ANGELES BY JET.]
- MAKE "NUMS [A NUMBER IS MULTIPLIED BY 6 . THIS PRODUCT IS INCREASED BY 44 . ~
- THIS RESULT IS 68 . FIND THE NUMBER.]
- MAKE "RADIO [THE PRICE OF A RADIO IS $69.70. ~
- IF THIS PRICE IS 15 PERCENT LESS THAN THE MARKED PRICE, FIND THE MARKED PRICE.]
- MAKE "SALLY [THE SUM OF SALLY'S SHARE OF SOME MONEY AND FRANK'S SHARE IS $4.50. ~
- SALLY'S SHARE IS TWICE FRANK'S. FIND FRANK'S AND SALLY'S SHARE.]
- MAKE "SHIP [THE GROSS WEIGHT OF A SHIP IS 20000 TONS. ~
- IF ITS NET WEIGHT IS 15000 TONS, WHAT IS THE WEIGHT OF THE SHIPS CARGO?]
- MAKE "SPAN [IF 1 SPAN IS 9 INCHES, AND 1 FATHOM IS 6 FEET, ~
- HOW MANY SPANS IS 1 FATHOM?]
- MAKE "SUMTWO [THE SUM OF TWO NUMBERS IS 96, ~
- AND ONE NUMBER IS 16 LARGER THAN THE OTHER NUMBER. FIND THE TWO NUMBERS.]
- MAKE "TOM [IF THE NUMBER OF CUSTOMERS TOM GETS IS ~
- TWICE THE SQUARE OF 20 PER CENT OF THE NUMBER OF ADVERTISEMENTS HE RUNS, ~
- AND THE NUMBER OF ADVERTISEMENTS HE RUNS IS 45, ~
- WHAT IS THE NUMBER OF CUSTOMERS TOM GETS?]
- MAKE "UNCLE [BILL'S FATHER'S UNCLE IS TWICE AS OLD AS BILL'S FATHER. ~
- 2 YEARS FROM NOW BILL'S FATHER WILL BE 3 TIMES AS OLD AS BILL. ~
- THE SUM OF THEIR AGES IS 92 . FIND BILL'S AGE.]
-
- PPROP "DISTANCE "EQNS ~
- [[EQUAL [DISTANCE] [PRODUCT [SPEED] [TIME]]] ~
- [EQUAL [DISTANCE] [PRODUCT [GAS CONSUMTION] [NUMBER OF GALLONS OF GAS USED]]]]
- PPROP "FEET "EQNS ~
- [[EQUAL [PRODUCT 1 [FEET]] [PRODUCT 12 [INCHES]]] ~
- [EQUAL [PRODUCT 1 [YARDS]] [PRODUCT 3 [FEET]]]]
- PPROP "FEET "SING "FOOT
- PPROP "FOOT "PLURAL "FEET
- PPROP "GALLONS "EQNS ~
- [[EQUAL [DISTANCE] [PRODUCT [GAS CONSUMTION] [NUMBER OF GALLONS OF GAS USED]]]]
- PPROP "GAS "EQNS ~
- [[EQUAL [DISTANCE] [PRODUCT [GAS CONSUMTION] [NUMBER OF GALLONS OF GAS USED]]]]
- PPROP "INCH "PLURAL "INCHES
- PPROP "INCHES "EQNS [[EQUAL [PRODUCT 1 [FEET]] [PRODUCT 12 [INCHES]]]]
- PPROP "PEOPLE "SING "PERSON
- PPROP "PERSON "PLURAL "PEOPLE
- PPROP "SPEED "EQNS [[EQUAL [DISTANCE] [PRODUCT [SPEED] [TIME]]]]
- PPROP "TIME "EQNS [[EQUAL [DISTANCE] [PRODUCT [SPEED] [TIME]]]]
- PPROP "YARDS "EQNS [[EQUAL [PRODUCT 1 [YARDS]] [PRODUCT 3 [FEET]]]]
-
-